/* eslint-disable */
import CryptoJS from 'crypto-js';
import md5 from 'md5';
import sha256 from 'sha256';

const appkey =
  '84_54_109_122_56_114_84_70_48_87_88_118_106_78_68_103_115_104_122_83_75_116_101_75_89_112_71_112_97_69_50_86'
    .split('_')
    .map((a) => String.fromCharCode(parseInt(a)))
    .join('');

const password = 'oaCIYzQ5gbaRj7F52iXVR6xEit5EMoIn';
const key = CryptoJS.enc.Utf8.parse(password);
const iv = CryptoJS.enc.Utf8.parse('3729Bw6OOrOWt7E9');

// @ts-ignore
const media_key = CryptoJS[
  String.fromCharCode(101) + String.fromCharCode(110) + String.fromCharCode(99)
][
  String.fromCharCode(85) +
    String.fromCharCode(116) +
    String.fromCharCode(102) +
    String.fromCharCode(56)
][`${String.fromCharCode(112)}arse`](
  '102_53_100_57_54_53_100_102_55_53_51_51_54_50_55_48'
    .split('_')
    .map((a) => String.fromCharCode(parseInt(a)))
    .join('')
);

// @ts-ignore
const media_iv = CryptoJS[
  String.fromCharCode(101) + String.fromCharCode(110) + String.fromCharCode(99)
][
  String.fromCharCode(85) +
    String.fromCharCode(116) +
    String.fromCharCode(102) +
    String.fromCharCode(56)
][`${String.fromCharCode(112)}arse`](
  '57_55_98_54_48_51_57_52_97_98_99_50_102_98_101_49'
    .split('_')
    .map((a) => String.fromCharCode(parseInt(a)))
    .join('')
);

//签名算法
function getSign(obj: any) {
  const keyValues = [];
  if (typeof obj.data !== 'undefined') {
    keyValues.push(`data=${obj.data}`);
  }
  if (typeof obj.timestamp !== 'undefined') {
    keyValues.push(`timestamp=${obj.timestamp}`);
  }
  const text = keyValues.join('&') + appkey;
  const sha256Text = sha256(text);
  const md5Text = md5(sha256Text);
  return md5Text;
}

export function DecryptImage(word: any) {
  // @ts-ignore
  const decrypt = CryptoJS[
    String.fromCharCode(65) + String.fromCharCode(69) + String.fromCharCode(83)
  ][
    '100_101_99_114_121_112_116'
      .split('_')
      .map((a) => String.fromCharCode(parseInt(a)))
      .join('')
  ](word, media_key, {
    iv: media_iv,
    // @ts-ignore
    mode: CryptoJS[
      '109_111_100_101'
        .split('_')
        .map((a) => String.fromCharCode(parseInt(a)))
        .join('')
    ][
      String.fromCharCode(67) +
        String.fromCharCode(66) +
        String.fromCharCode(67)
    ],
    padding:
      // @ts-ignore
      CryptoJS[`${String.fromCharCode(112)}ad`][
        `${String.fromCharCode(78)}o${String.fromCharCode(80)}adding`
      ],
  });
  const decryptedStr = decrypt.toString(CryptoJS.enc.Base64);
  return decryptedStr;
}

export function DecryptVideo(word: any) {
  // @ts-ignore
  const decrypt = CryptoJS[
    String.fromCharCode(65) + String.fromCharCode(69) + String.fromCharCode(83)
  ][
    '100_101_99_114_121_112_116'
      .split('_')
      .map((a) => String.fromCharCode(parseInt(a)))
      .join('')
  ](word, media_key, {
    iv: media_iv,
    // @ts-ignore
    mode: CryptoJS[
      '109_111_100_101'
        .split('_')
        .map((a) => String.fromCharCode(parseInt(a)))
        .join('')
    ][
      String.fromCharCode(67) +
        String.fromCharCode(66) +
        String.fromCharCode(67)
    ],
    // @ts-ignore
    padding: CryptoJS[`${String.fromCharCode(112)}ad`].Pkcs7,
  });
  const decryptedStr = decrypt.toString(
    // @ts-ignore
    CryptoJS[
      String.fromCharCode(101) +
        String.fromCharCode(110) +
        String.fromCharCode(99)
    ][
      String.fromCharCode(85) +
        String.fromCharCode(116) +
        String.fromCharCode(102) +
        String.fromCharCode(56)
    ]
  );
  return decryptedStr;
}

//加密方法
export function Encrypt(word: any) {
  // 问题二. 参数如为对象类型, 前转为字符串类型(xifeng update)
  if (typeof word == 'object') {
    word = JSON.stringify(word);
  }

  const srcs = CryptoJS.enc.Utf8.parse(word);
  const { key: newKey, iv: newIv } = keyGenerator(password, 32, 16);

  const encrypted = CryptoJS.AES.encrypt(srcs, newKey, {
    iv: newIv,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding,
  });

  const data = newIv
    .concat(encrypted.ciphertext)
    .toString(CryptoJS.enc.Hex)
    .toUpperCase();

  const unix_t = new Date().getTime() / 1000;
  const timestamp = parseInt(unix_t.toString());
  const sign = getSign({ data, timestamp });
  return { sign, timestamp, data };
}

//解密方法
export function Decrypt(word: any) {
  let encryptedHexStr = CryptoJS.enc.Base64.parse(word);
  let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  let decrypt = CryptoJS.AES.decrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return JSON.parse(decryptedStr.toString());
}

// IM密钥
const im_key = CryptoJS.enc.Utf8.parse('Ksl5I9PXK63EdiJh');
const im_iv = CryptoJS.enc.Utf8.parse('fyMqKuq1a4n0PJwf');

// IM解密
export function DecryptIm(word: string) {
  const encryptedHexStr = CryptoJS.enc.Base64.parse(word);
  const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  const decrypt = CryptoJS.AES.decrypt(srcs, im_key, {
    iv: im_iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  return JSON.parse(decryptedStr.toString());
}

// IM加密
export function EncryptIm(word: string) {
  if (typeof word == 'object' && word !== null) word = JSON.stringify(word);
  const srcs = CryptoJS.enc.Utf8.parse(word);
  const encrypted = CryptoJS.AES.encrypt(srcs, im_key, {
    iv: im_iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  let data = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  return data;
}

function keyGenerator(password: string, keyLen: number, ivLen: number) {
  let derivedBytes = CryptoJS.lib.WordArray.create();
  let block = null;
  let combinedPassword = CryptoJS.enc.Utf8.parse(password);

  while (derivedBytes.sigBytes < keyLen) {
    if (block) {
      block = CryptoJS.MD5(block.concat(combinedPassword));
    } else {
      block = CryptoJS.MD5(combinedPassword);
    }
    derivedBytes.concat(block);
  }

  const key = CryptoJS.lib.WordArray.create(
    derivedBytes.words.slice(0, keyLen / 4),
    keyLen
  );
  const iv = CryptoJS.lib.WordArray.random(ivLen);

  return { key, iv };
}
